package chaincode

import (
    "encoding/json"
    "github.com/hyperledger/fabric-chaincode-go/shim"
    "github.com/hyperledger/fabric-protos-go/peer"
)

// Asset 定义资产结构体
type Asset struct {
    ID       string `json:"id"`
    Name     string `json:"name"`
    Info     string `json:"info"`
    Owner    string `json:"owner"`
}

// SmartContract 定义智能合约结构体
type SmartContract struct{}

// Init 初始化链码
func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) peer.Response {
    return shim.Success(nil)
}

// Invoke 调用链码函数
func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
    function, args := stub.GetFunctionAndParameters()
    switch function {
    case "CreateAsset":
        return s.CreateAsset(stub, args)
    case "TransferAsset":
        return s.TransferAsset(stub, args)
    case "QueryAsset":
        return s.QueryAsset(stub, args)
    default:
        return shim.Error("Invalid function name")
    }
}

// CreateAsset 创建资产
func (s *SmartContract) CreateAsset(stub shim.ChaincodeStubInterface, args []string) peer.Response {
    if len(args) != 4 {
        return shim.Error("Incorrect number of arguments. Expecting 4")
    }
    asset := Asset{
        ID:       args[0],
        Name:     args[1],
        Info:     args[2],
        Owner:    args[3],
    }
    assetJSON, err := json.Marshal(asset)
    if err != nil {
        return shim.Error("Failed to marshal asset")
    }
    err = stub.PutState(args[0], assetJSON)
    if err != nil {
        return shim.Error("Failed to put asset to state")
    }
    return shim.Success(nil)
}

// TransferAsset 转移资产
func (s *SmartContract) TransferAsset(stub shim.ChaincodeStubInterface, args []string) peer.Response {
    if len(args) != 2 {
        return shim.Error("Incorrect number of arguments. Expecting 2")
    }
    assetID := args[0]
    newOwner := args[1]
    assetJSON, err := stub.GetState(assetID)
    if err != nil {
        return shim.Error("Failed to get asset from state")
    }
    if assetJSON == nil {
        return shim.Error("Asset does not exist")
    }
    var asset Asset
    err = json.Unmarshal(assetJSON, &asset)
    if err != nil {
        return shim.Error("Failed to unmarshal asset")
    }
    asset.Owner = newOwner
    updatedAssetJSON, err := json.Marshal(asset)
    if err != nil {
        return shim.Error("Failed to marshal updated asset")
    }
    err = stub.PutState(assetID, updatedAssetJSON)
    if err != nil {
        return shim.Error("Failed to update asset in state")
    }
    return shim.Success(nil)
}

// QueryAsset 查询资产
func (s *SmartContract) QueryAsset(stub shim.ChaincodeStubInterface, args []string) peer.Response {
    if len(args) != 1 {
        return shim.Error("Incorrect number of arguments. Expecting 1")
    }
    assetID := args[0]
    assetJSON, err := stub.GetState(assetID)
    if err != nil {
        return shim.Error("Failed to get asset from state")
    }
    if assetJSON == nil {
        return shim.Error("Asset does not exist")
    }
    return shim.Success(assetJSON)
}    